package xxl;
import java.util.Random;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Cursor;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.Timer;

import java.io.File;
import java.io.IOException;

class GameRoom extends JFrame {
	private static final long serialVersionUID = 6833027888091342164L;
	private final int ANIMAL_WIDTH = 48;    //动物图片的宽度
    private final int ANIMAL_HEIGHT = 48;    //动物图片的高度
    private final int ANIMAL_NUM = 7;        //动物数量
    private final int DDP_MATRIX_ROW = 8;
    private final int DDP_MATRIX_COL = 8;
    private final int EMPTY = 7;    //对对碰矩阵值空时的标记
    private boolean isThreeLinked;    //标记是否有三个以上的连接
    //标记单击次数
    private boolean isDoubleClicked;
    private int x1;    //记录第一次被点击的X坐标
    private int y1;    //记录第一次被点击的Y坐标
    private BufferedImage roomBackground;    //房间的图片背景
    //随机数
    private Random rand = new Random();    
    //动物数组
    private int[][] animal =
        new int[DDP_MATRIX_ROW][DDP_MATRIX_COL];    
    private BufferedImage pool;
    private BufferedImage[] animalImage = new BufferedImage[ANIMAL_NUM];
    private RoomPanel roomPanel = new RoomPanel();//游戏区面板
	JTextField textarea1 = new JTextField(10);    //显示分数
	JTextField textarea2 = new JTextField(10);    //显示剩余时间
    private int grade = 0; //得分
    private Timer timer;   //定时器
    


	//消除三个以上连接的点
	private void removeLinked(int x, int y) {
		if(animal[x][y] == EMPTY)return;
		int n=0;
		int tmp;
		int linked = 1;
		if (x + 1 < 8) {
			tmp = x + 1;
			while (tmp < 8 && animal[x][y] == animal[tmp][y]) {
				linked++;
				tmp++;
			}
		}
		if (x - 1 >= 0) {
			tmp = x - 1;
			while (tmp >= 0 && animal[x][y] == animal[tmp][y]) {
				linked++;
				tmp--;
			}
		}		
		if (linked >= 3) {
			n=n+linked; 
			tmp = x + 1;
			while (tmp < 8 && animal[tmp][y] == animal[x][y]) {				
				animal[tmp][y] = EMPTY;
				tmp++;
			}
			tmp = x - 1;
			while (tmp >= 0 && animal[tmp][y] == animal[x][y]) {
				animal[tmp][y] = EMPTY;
				tmp--;
			}
			// 当前交换过来的点
			animal[x][y] = EMPTY;
		}
		tmp = 0;
		linked = 1;
		if (y + 1 < 8) {
			tmp = y + 1;
			while (tmp < 8 && animal[x][y] == animal[x][tmp]) {
				linked++;
				tmp++;
			}
		}
		if (y - 1 >= 0) {
			tmp = y - 1;
			while (tmp >= 0 && animal[x][y] == animal[x][tmp]) {
				linked++;
				tmp--;
			}
		}
		if (linked >= 3) {
			n=n+linked; 
			tmp = y + 1;
			while (tmp < 8 && animal[x][y] == animal[x][tmp]) {
				animal[x][tmp] = EMPTY;
				tmp++;
			}
			tmp = y - 1;
			while (tmp >= 0 && animal[x][y] == animal[x][tmp]) {
				animal[x][tmp] = EMPTY;
				tmp--;
			}
			// 当前交换过来的点
			animal[x][y] = EMPTY;
		}		
		grade+=n*10;
		textarea1.setText(Integer.toString(grade));
		System.out.println(grade + " ======"+x+" "+y);
	}

    /*功能:全局扫描三个相连相同的点
     *@param: flag flag为1时:只判断是否有三个相连的点
     *             flag为2时:删除三个相连的点
     */
    private boolean globalSearch(int flag) {//**
        if (1 == flag) {
            for (int i = 0; i < DDP_MATRIX_ROW; i++) {
                for (int j = 0; j < DDP_MATRIX_COL; j++) {
                    if (isThreeLinked(i, j)) {
                        return true;
                    }
                }
            }
        } else if (2 == flag) {
            for (int i = 0; i < DDP_MATRIX_ROW; i++) {
                for (int j = 0; j < DDP_MATRIX_COL; j++) {
                    //删除三个相连的点
                    removeLinked(i, j);
                }
            }
        }
        return false;
    }

    //是否有三个以上连接的点
    private boolean isThreeLinked(int x, int y) {
        int tmp;
        int linked = 1;
        if (x + 1 < DDP_MATRIX_ROW) {
            tmp = x + 1;
            while (tmp < DDP_MATRIX_ROW 
                && animal[x][y] == animal[tmp][y]) {
                linked++;
                tmp++;
            }
        }
        if (x - 1 >= 0) {
            tmp = x - 1;
            while (tmp >= 0 
                && animal[x][y] == animal[tmp][y]) {
                linked++;
                tmp--;
            }
        }
        if (linked >= 3) {
/*            tmp = x + 1;
            while (tmp < DDP_MATRIX_ROW 
                && animal[tmp][y] == animal[x][y]) {
                tmp++;
            }
            tmp = x - 1;
            while (tmp >= 0 
                && animal[tmp][y] == animal[x][y]) {
                tmp--;
            }*/
            return true;
        }

        linked = 1;
        if (y + 1 < DDP_MATRIX_COL) {
            tmp = y + 1;
            while (tmp < DDP_MATRIX_COL 
                && animal[x][y] == animal[x][tmp]) {
                linked++;
                tmp++;
            }
        }
        if (y - 1 >= 0) {
            tmp = y - 1;
            while (tmp >= 0 
                && animal[x][y] == animal[x][tmp]) {
                linked++;
                tmp--;
            }
        }
        if (linked >= 3) {
/*            tmp = y + 1;
            while (tmp < DDP_MATRIX_COL 
                && animal[x][y] == animal[x][tmp]) {
                tmp++;
            }
            tmp = y - 1;
            while (tmp >= 0 
                && animal[x][y] == animal[x][tmp]) {
                tmp--;
            }*/
            return true;
        }
        return false;
    }


    //更新动物矩阵
    private void updateAnimal() {
        for (int i = 0; i < DDP_MATRIX_ROW; i++) {
            for (int j = 0; j < DDP_MATRIX_COL; j++) {
                if (animal[i][j] == EMPTY) {
                    //将矩阵中为空值的点再进行随机赋值
                    animal[i][j] = rand.nextInt(ANIMAL_NUM);
                }
            }
        }
    }

    //动物下降
//    private void downAnimal() {
//        int tmp;
//        for (int j = DDP_MATRIX_COL - 1; j >= 0; j--) {
//            for (int i = 0; i < DDP_MATRIX_ROW; i++) {
//            	//第i列j行为空（被削去动物)
//                if (animal[j][i] == EMPTY) {
//                	//第i列上方动物下移
//                    for (int k = j - 1; k >= 0; k--) {
//                            tmp = animal[k][i];
//                            animal[k][i] = animal[k+1][i];
//                            animal[k+1][i] = tmp;                            
//                    }
//                }
//            }
//        }
//    }
    //动物下降
    private void downAnimal() {
        int tmp;
        for (int j = DDP_MATRIX_COL - 1; j >= 0; j--) {
            for (int i = 0; i < DDP_MATRIX_ROW; i++) {
                if (animal[j][i] == EMPTY) {
                    for (int k = j - 1; k >= 0; k--) {
                        if (animal[k][i] != EMPTY) {
                            tmp = animal[k][i];
                            animal[k][i] = animal[j][i];
                            animal[j][i] = tmp;
                            break;
                        }
                    }
                }
            }
        }
    }
    private void print() {
        for (int i = 0; i < DDP_MATRIX_ROW; i++) {
            for (int j = 0; j < DDP_MATRIX_COL; j++) {
                System.out.print(animal[i][j]);
                if (j == 7) {
                    System.out.println();
                }
            }
        }   
    }
    
    //交换动物图案
    private void swapAnimal(int x, int y) {
    	if ((x >= 203 && x <= 587) 
    			&& (y >= 95 && y <= 479)) {

    		//被点击的动物的坐标的绝对值
    		int xAbs;
    		int yAbs;
    		xAbs = (x - 203) / ANIMAL_WIDTH;
    		yAbs = (y - 66) / ANIMAL_HEIGHT;
    		System.out.println("xAbs = " + xAbs);
    		System.out.println("yAbs = " + yAbs);

    		if (!isDoubleClicked) {
    			isDoubleClicked = true;
    			x1 = xAbs;
    			y1 = yAbs;
    			System.out.println("被单击的点的X坐标 = " + x1);
    			System.out.println("被单击的点的Y坐标 = " + y1);
    			repaint();
    		} else {    			
	    		int x2 = xAbs ;
	    		int y2 = yAbs;
    			isDoubleClicked = false;
    			//两点的坐标绝对值等于1时视为相邻的两点
    			if (1 == Math.abs(x2 - x1) && y2 == y1
    					|| 1 == Math.abs(y2 - y1)&& x2 == x1) {
    				//-------------交换矩阵中相邻的两点的值--------------
    				int tmp;
    				tmp = animal[y2][x2];
    				animal[y2][x2] = animal[y1][x1];
    				animal[y1][x1] = tmp;
    				//-----------------------------------------------------

    				if (isThreeLinked(y2, x2)||isThreeLinked(y1, x1)) {
    					System.out.println("消除点");
    					if(isThreeLinked(y2, x2))
    						removeLinked(y2, x2);
    					if(isThreeLinked(y1, x1))
    						removeLinked(y1, x1);
    					downAnimal();//被削去处上方的动物下降
    					//该列上方重新随机产生新的动物，更新动物矩阵
    					updateAnimal();
    					print();
    					repaint();
    					//全局扫描判断是否有新的三个以上连接点，有则删除
    					while (globalSearch(1)) {
    						//全局扫描消除三个以上相连的点
    						globalSearch(2);
    						//动物再次下落
    						downAnimal();
    						//再次更新动物矩阵
    						updateAnimal();
    						repaint();
    					}  
    				}
    				else {//没有三个以上相同的点，交换回来  
    					System.out.println("交换回来");
    					tmp = animal[y1][x1];
    					animal[y1][x1] = animal[y2][x2];
    					animal[y2][x2] = tmp;
    					print(); 
    					//选中第二次单击的动物
    	    			isDoubleClicked = true;
    	    			x1 = xAbs;
    	    			y1 = yAbs;
    	    			repaint();
    				}
    			}
    		}
    	}
    }

    //加载所有图片
    private void initImage() {
        try {

            //加载背景图片
            roomBackground = ImageIO.read(new File("image/room.jpg"));
            //加载所有动物
            animalImage[0] = ImageIO.read(new File("image/monkey.png"));
            animalImage[1] = ImageIO.read(new File("image/fox.png"));
            animalImage[2] = ImageIO.read(new File("image/frog.png"));
            animalImage[3] = ImageIO.read(new File("image/chicken.png"));
            animalImage[4] = ImageIO.read(new File("image/cattle.png"));
            animalImage[5] = ImageIO.read(new File("image/cat.png"));
            animalImage[6] = ImageIO.read(new File("image/panda.png"));
            //加载动物池图片
            pool = ImageIO.read(new File("image/pool.jpg"));

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
    public GameRoom(){
    	JLabel label1 = new JLabel("分数");
    	JLabel label2 = new JLabel("时间");
    	JPanel panel1 = new JPanel(); 
    	this.setLayout(new BorderLayout());
		panel1.setLayout(new FlowLayout());
		panel1.add(label1);
		panel1.add(textarea1);
		textarea1.setEditable(false);
		textarea1.setText(Integer.toString(grade));//显示得分
		textarea2.setText(Integer.toString(100)+"秒");
		panel1.add(label2);	
		panel1.add(textarea2);
		this.add(panel1, BorderLayout.NORTH);
		this.add(roomPanel,BorderLayout.CENTER); 
		initImage();
    }
    //初始化动物数组
    private void initAnimalMatrix() {
        for (int i = 0; i < DDP_MATRIX_ROW; i++) {
            for (int j = 0; j < DDP_MATRIX_COL; j++) {
                //随机选取动物
                animal[i][j] = rand.nextInt(7);
            }
        }    
    }
    public void init() {
        do {
            System.out.println("重新初始化");
            initAnimalMatrix();
        } while (globalSearch(1));
        print();        

        //设置房间最佳大小
        roomPanel.setPreferredSize
            (new Dimension(roomBackground.getWidth()
            , roomBackground.getHeight()));
        
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                setMouseCurHand(x, y);
            }
        });

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("x = " + e.getX());
                System.out.println("y = " + e.getY());
                swapAnimal(e.getX(), e.getY());
            }
        });          
        
        setTitle("对对碰");
        pack();
        setResizable(false);
        setVisible(true);
        timer = new Timer(800, new TimeListener());
		timer.start();
		grade = 0;
    }
    
    //设置鼠标进入某区域内鼠标显示的图标
    private void setMouseCurHand(int x, int y) {
        //进入动物图案区域
    	if ((x >= 203 && x <= 587) 
    			&& (y >= 65 && y <= 445)) {
            //设置为手状
            setCursor(new Cursor(Cursor.HAND_CURSOR));
        } else 
            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }

    class RoomPanel extends JPanel {
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D)g;
            //绘制背景图片
            g2d.drawImage(roomBackground, 0, 0
                , roomBackground.getWidth()
                , roomBackground.getHeight(), null);

            //绘制动物池
            g2d.drawImage(pool, 200, 0, 384, 384, null);
            
            //在动物池中绘制所有动物
            for (int i = 0; i < DDP_MATRIX_ROW; i++) {
                for (int j = 0; j < DDP_MATRIX_COL; j++) {
                    g2d.drawImage(animalImage[animal[i][j]]
                        , 200 + j * 48,  i * 48
                        , ANIMAL_WIDTH, ANIMAL_HEIGHT, null);
                }
            }
            //g2d.setColor(Color.RED);
    		g2d.drawRect(200 +x1* 48,  y1 * 48, 48, 48);        

        }
    }
    class TimeListener implements ActionListener {
    	int times = 0;
    	public void actionPerformed(ActionEvent e) {
    		times++;
    		if (times > 100) {
    			timer.stop();
    			//定时器结束
    			int answer=JOptionPane.showConfirmDialog(null,
    					"游戏结束,是否继续", "游戏结束",
    					JOptionPane.YES_NO_OPTION);
    			if(answer== JOptionPane.YES_OPTION)
    				init();
    			else
    				System.exit(0);
    		}else
    			textarea2.setText(Integer.toString(100-times)+"秒");    		
    	}
    }
    public static void main(String[] args) {
		new GameRoom().init();
	}
}
